package com.chalk.config.security;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;

/**
 * ClassName: SpringContextUtil
 *
 * @author L.G
 * @Description SpringContext 工具类
 * @email lg10000@126.com
 * @date 2018年7月11日 上午11:08:26
 */
@Component
public class SpringContextUtil implements ApplicationContextAware {

    private static final Logger LOGGER = LoggerFactory.getLogger(SpringContextUtil.class);

    /* 上下文对象 */
    private static ApplicationContext applicationContext;

    /* model包名 */
    private static final String MODEL_PACKAG_ENAME = "com.chalk.chan.model";

    private static final String SPOT = ".";

    @SuppressWarnings("static-access")
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    /* 获取applicationContext */
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    /* 通过name获取 Bean */
    public static Object getBean(String name) {
        return getApplicationContext().getBean(name);
    }

    /* 通过class获取Bean */
    public static <T> T getBean(Class<T> clazz) {
        return getApplicationContext().getBean(clazz);
    }

    /* 通过name,以及Clazz返回指定的Bean */
    public static <T> T getBean(String name, Class<T> clazz) {
        return getApplicationContext().getBean(name, clazz);
    }

    /**
     * 通过实体名称获取实体类
     *
     * @param modelName 实体名称(例如:UserInfoModel)
     * @return
     */
    public static Class<?> getClass(String modelName) {
        try {
            if (StringUtils.isNotBlank(modelName)) {
                StringBuffer modelPackag = new StringBuffer(MODEL_PACKAG_ENAME).append(SPOT).append(modelName);
                return Class.forName(modelPackag.toString());
            } else {
                LOGGER.info("获取model异常:mode名称不能为空。");
            }
        } catch (Exception e) {
            LOGGER.error("获取model异常:" + ExceptionUtils.getStackTrace(e));
        }
        return null;
    }

    /**
     * 获取token
     *
     * @param request 请求
     * @return token
     */
    public static String extractHeaderToken(HttpServletRequest request) {
        Enumeration<String> headers = request.getHeaders("Authorization");
        while (headers.hasMoreElements()) { // typically there is only one (most servers enforce that)
            String value = headers.nextElement();
            if ((value.toLowerCase().startsWith(OAuth2AccessToken.BEARER_TYPE.toLowerCase()))) {
                String authHeaderValue = value.substring(OAuth2AccessToken.BEARER_TYPE.length()).trim();
                // Add this here for the auth details later. Would be better to change the signature of this method.
                request.setAttribute(OAuth2AuthenticationDetails.ACCESS_TOKEN_TYPE,
                        value.substring(0, OAuth2AccessToken.BEARER_TYPE.length()).trim());
                int commaIndex = authHeaderValue.indexOf(',');
                if (commaIndex > 0) {
                    authHeaderValue = authHeaderValue.substring(0, commaIndex);
                }
                return authHeaderValue;
            }
        }
        return null;
    }

}
